package com.bw.documents.manager

import android.util.Log
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.bw.common.mvi.BaseViewModel
import com.bw.documents.manager.entity.DocumentsEntity
import com.bw.documents.manager.entity.DocumentsResponseEntity
import com.bw.documents.manager.entity.DocumentsState
import com.bw.network.BaseEntity
import com.bw.network.download.DownloadManager
import com.bw.network.download.DownloadStatus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.io.File
import java.util.HashMap

class DocumentsViewModel : BaseViewModel<DocumentsRepo, DocumentsState>() {

    private var page = 1

    override fun createRepo(): DocumentsRepo {return DocumentsRepo() }

    override fun createState(): DocumentsState {
        return DocumentsState(
            documentsState = false,
            loadState = false,
            data = ArrayList<DocumentsEntity>(),
            delSate = false,
            insertState = false,
            syncState = false,
            uploadState = false,
            downloadState = false,
            path = ""
        )
    }
    //获取文件列表
    fun selDocuments(userId:Long){
        page = 1
        viewModelScope.launch {
            val map = HashMap<String,Any>()
            map["userId"] = userId
            map["page"] = page
            subFlow( repo.selDocuments(map))
                .collect{
                    val entity : DocumentsResponseEntity = it as DocumentsResponseEntity
                    Log.e("ZXY","vm->documentsState+${entity.totalNum},size:${entity.data[0]}")
                    mutableContainer.updateUiState {
                        copy(documentsState=true,loadState = false,entity.data,
                            delSate = false, insertState = false, syncState = false,false) }
                }
        }
    }
    //加载文件列表
    fun loadDocuments(userId:Long){
        page += 1
        viewModelScope.launch {
            val map = HashMap<String,Any>()
            map["userId"] = userId
            map["page"] = page
            subFlow( repo.selDocuments(map))
                .collect{
                    val entity : DocumentsResponseEntity = it as DocumentsResponseEntity
                    mutableContainer.updateUiState {
                        copy(documentsState=false,loadState = true, data = entity.data,
                            delSate = false, insertState = false, syncState = false, uploadState = false
                        ) }
                }
        }
    }
    //添加文件
    fun insertDocuments(path : String,name : String,userId: Long){
        val map = HashMap<String,Any>()
        map["userId"] = userId
        map["path"] = path
        map["name"] = name
        viewModelScope.launch {
            subFlow(repo.uploadDocuments(map))
                .flatMapConcat { value ->
                    requestInsertDocuments(map,value)
                }.collect{
                    if (it.statusCode == 100){
                        //请求失败
                        ToastUtils.showShort("文件大于1MB上传失败")
                    }else{
                        mutableContainer.updateUiState {
                            copy(documentsState = false,loadState = false,
                                delSate = false, insertState = true, syncState = false) }
                    }
                }
        }
    }
    //删除文件
    fun delDocuments(FileId : Long){
        val map = HashMap<String,Any>()
        map["FileId"] = FileId
        viewModelScope.launch {
            subFlow(repo.delDocuments(map))
                .collect{
                    ToastUtils.showShort(it.msg)
                    if (it.msg.equals("删除成功")){
                        mutableContainer.updateUiState {
                            copy(documentsState = false,loadState=false,
                                delSate = true, insertState = false, uploadState = false,
                                syncState = false) }
                        selDocuments(1)
                    }
                }
        }
    }
    //同步文件
    fun syncDocuments(entity: DocumentsEntity){
        val uploadMap = HashMap<String,Any>()
        uploadMap["path"]=entity.filePath
        uploadMap["name"]=entity.fileName
        viewModelScope.launch {
            subFlow(repo.uploadDocuments(uploadMap))
                .flatMapConcat { value ->  requestSyncDocuments(entity,value)}
                .collect{
                    if (it.statusCode == 100){
                        //请求失败
                        ToastUtils.showShort("文件大于1MB同步失败")
                    }else{
                        mutableContainer.updateUiState {
                            copy(documentsState = false,loadState = false,
                                delSate = false, insertState = false, syncState = true) }
                    }
                }
        }
    }
    //下载文件
    fun downloadFile(urlStr : String,path : String){
        viewModelScope.launch {
            DownloadManager.download(urlStr, File(path)).flowOn(Dispatchers.IO)
                .catch { t : Throwable->
                    LogUtils.e("errorMsg:${t.message}")  }
                .collect{
                    if(it is DownloadStatus.Err){
                        ToastUtils.showShort("加载失败")
                    }
                    if (it is DownloadStatus.Done)
                        mutableContainer.updateUiState {
                            copy(downloadState = true, path = path) }
                }
        }
    }
    private fun requestSyncDocuments(entity: DocumentsEntity, value: BaseEntity):Flow<BaseEntity>{
        return if (value.statusCode == 100){
            flow { emit(value) }
        }else{
            val map = HashMap<String,Any>()
            map["FileUserId"] = entity.fileUserId
            map["FileVersion"] = entity.fileVersion
            map["FilePath"] = "http://localhost:8080/fileDownload?fileName="+entity.fileName
            map["FileName"] = entity.fileName
            map["FileId"] = entity.fileId
            repo.syncDocuments(map)
        }
    }

    private fun requestInsertDocuments(map : HashMap<String,Any>,value : BaseEntity):Flow<BaseEntity>{
        if (value.statusCode == 100){
            return flow { emit(value) }
        }else{
            map["path"]="http://localhost:8080/fileDownload?fileName="+map["name"]
            return repo.insertDocuments(map).flowOn(Dispatchers.IO)
        }
    }

//    private fun subFlow(flow: Flow<BaseEntity>):Flow<BaseEntity>{
//        return flow.flowOn(Dispatchers.IO)
//            .catch { t : Throwable->
//                LogUtils.e("errorMsg:${t.message}") }
//            .onStart { mutableContainer.updateRequestState { copy(request=true,complate = false) } }
//            .onCompletion { mutableContainer.updateRequestState { copy(request=false,complate = true) } }
//    }

}